using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Hosting;
using ScriptBehind.Core;
using ScriptBehind.Core.Interfaces;
using ScriptBehind.Extensions;

namespace ScriptBehind.Scripts
{
    public sealed class EmbededScript : ScriptBase
    {
        EmbededScript(string content, string filename, InjectPosition injectPosition, ICompressionStrategy compression) 
        {
            Content = content;
            FileName = filename;
            InjectPosition = injectPosition;
            Compression = compression;
        }

        public string Content { get; set; }

        public override IInjectionFormatter Formatter
        {
            get { return new EmbededInjectionFormatter(); }
        }

        public override void TryConstruct(string from)
        {
            if (Regex.IsMatch(from, @"[\s\{]"))
                ContentIs(from, Guid.NewGuid().ToString());
        }

        public static EmbededScript ContentIs(string content, string filename)
        {
            return ContentIs(content, filename, Core.InjectPosition.Inline, ScriptBehindCore.DefaultCompression);
        }

        public static EmbededScript ContentIs(string content, string filename, InjectPosition injectPosition)
        {
            return ContentIs(content, filename, injectPosition, ScriptBehindCore.DefaultCompression);
        }

        public static EmbededScript ContentIs(string content, string filename, InjectPosition injectPosition, ICompressionStrategy compression)
        {
            return new EmbededScript(content, filename, injectPosition, compression);
        }

        public static EmbededScript ContentIs(string content, string filename, ICompressionStrategy compression)
        {
            return new EmbededScript(content, filename, Core.InjectPosition.Default, compression);
        }

        public static EmbededScript FromFile(string filePath)
        {
            return FromFile(filePath, Core.InjectPosition.Default);
        }

        public static EmbededScript FromFile(string filePath, InjectPosition injectPosition)
        {
            return FromFile(filePath, injectPosition, ScriptBehindCore.DefaultCompression);
        }

        public static EmbededScript FromFile(string filePath, ICompressionStrategy compression)
        {
            return FromFile(filePath, Core.InjectPosition.Default, compression);
        }

        public static EmbededScript FromFile(string filePath, InjectPosition injectPosition, ICompressionStrategy compression)
        {
            var fullPath = HostingEnvironment.MapPath(filePath);

            if (fullPath == null || !File.Exists(fullPath))
                throw new FileNotFoundException("Content file for EmbededScript not found", filePath);

            var content = File.ReadAllText(fullPath);

            return ContentIs(content, Path.GetFileName(filePath), injectPosition, compression);
        }
    }

    public class EmbededInjectionFormatter : InjectionFormatter
    {
        public EmbededInjectionFormatter()
            : base("<script type='text/javascript'>{0}</script>")
        {
        }

        public override string Format(IScript script, bool seperate)
        {
            var typedScript = script as EmbededScript;

            if (typedScript == null)
                return null;

            return seperate
                       ? InjectionFormatString.FormatWith(typedScript.Content)
                       : typedScript.Content;
        }

        public override string Format(IEnumerable<IScript> scripts, bool seperate)
        {
            return scripts == null ? null : scripts.Select(x => Format(x, seperate)).Join("\r\n");
        }
    }
}